home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / invocCache.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-16  |  5.7 KB  |  201 lines

  1. /*
  2.  * @(#)invocCache.c    1.1  6/29/87
  3.  */
  4. #include "assert.h"
  5. #include "nodes.h"
  6. #include "symbols.h"
  7. #include "sequence.h"
  8. #include "system.h"
  9. #include "trace.h"
  10. #include "opNames.h"
  11. #include "option.h"
  12. #include "ndbm.h"
  13.  
  14. /*
  15.  * Imported routines.
  16.  */
  17. extern NodePtr
  18.     findManifestValue(),
  19.     figureOutAT(),
  20.     findObjectOperation(),
  21.     OTLookup();
  22.  
  23. extern Boolean
  24.     isPossibleAnswer();
  25. extern void
  26.     scheduleOutput(),
  27.     ensureGenerate();
  28. DBM *emDBM;
  29.  
  30. static Boolean buildKey(target, opName, formals, args, thekeyptr)
  31. NodePtr target, opName, formals, args;
  32. char *thekeyptr;
  33. {
  34.   NodePtr arg, formal, exp;
  35.   char *thekey = thekeyptr;
  36.   Boolean foundTypeVariable = FALSE;
  37. #define ADD1(s) {sprintf(thekey, s); thekey += strlen(thekey); }
  38. #define ADD2(s, v) {sprintf(thekey, s, v); thekey += strlen(thekey); }
  39.   if (target->b.oblit.f.isTypeVariable ||
  40.       target->b.oblit.f.dependsOnTypeVariable) {
  41.     foundTypeVariable = TRUE;
  42.   }
  43.   ADD2("O0x%08x.", target->b.oblit.id);
  44.   ADD2("0x%08x[", opName->b.opname.id);
  45.   Sequence_For(arg, args)
  46.     formal = formals->b.children[z__z];
  47.     assert(arg->tag == P_ARG);
  48.     exp = arg->b.arg.exp;
  49.     exp = findManifestValue(exp);
  50.     assert(exp != NN);
  51.     assert(exp->tag == P_ATLIT || exp->tag == P_OBLIT);
  52.     if (formal->b.param.constraint != NN) {
  53.       /* 
  54.        * this is a parameter that is to be a type, so figure the type of
  55.        * the argument.
  56.        */
  57.       exp = figureOutAT(exp);
  58.       assert(exp->tag == P_ATLIT);
  59.     }
  60.     if (exp->b.oblit.f.isTypeVariable ||
  61.       exp->b.oblit.f.dependsOnTypeVariable) {
  62.       foundTypeVariable = TRUE;
  63.     }
  64.     ADD2("O0x%08x", exp->b.oblit.id);
  65.     if (z__z < Sequence_Length(args) - 1) ADD1(",");
  66.   Sequence_Next
  67.   ADD1("]");
  68. #undef ADD1
  69. #undef ADD2
  70.   return(foundTypeVariable);
  71. }
  72.  
  73. NodePtr checkInvocCache(p)
  74. NodePtr p;
  75. {
  76.   NodePtr theOp, theSig, formals, target, opName, result = NN, args;
  77.   char thekeyspace[200], thevaluespace[32];
  78.   datum keydatum, valuedatum;
  79.   OID resultOID;
  80.   Boolean foundTypeVariable = FALSE;
  81.  
  82.   assert(p->tag == P_INVOC);
  83.   target = p->b.invoc.target;
  84.   target = findManifestValue(target);
  85.   assert(target->tag == P_OBLIT);
  86.   opName = p->b.invoc.opname;
  87.   assert(opName->tag == P_OPNAME);
  88.   TRACE3(invoccache, 1,
  89.     "looking in cache for invocation \"%s\" on \"%s\" on line %d",
  90.     ON_Name(opName->b.opname.id),
  91.     ST_SymbolName(target->b.oblit.name->b.symdef.symbol),
  92.     opName->lineNumber);
  93.  
  94.   if (target->b.oblit.id == 0) {
  95.     TRACE0(invoccache, 1, "Cannot execute invocation on oblit without id");
  96.     return(NN);
  97.   }
  98.  
  99.  
  100.   theOp = findObjectOperation(target, opName);
  101.   assert(theOp != NN);
  102.   assert(theOp->tag == P_OPDEF);
  103.  
  104.   theSig = theOp->b.opdef.sig;
  105.   assert(theSig->tag == P_OPSIG);
  106.   formals = theSig->b.opsig.params;
  107.   args = p->b.invoc.args;
  108.   /*
  109.    * First try to see if the invocation has been done previously by some
  110.    * other compiler since the beginning of time.
  111.    */
  112.   foundTypeVariable = buildKey(target, opName, formals, args, thekeyspace);
  113.   if (foundTypeVariable) {
  114.     TRACE0(invoccache, 2, "EI: Non-manifest arguments (or target)");
  115.   }
  116.   TRACE1(invoccache, 2, "EI: The key is %s", thekeyspace);
  117.   keydatum.dptr = thekeyspace;
  118.   keydatum.dsize = strlen(thekeyspace);
  119.   valuedatum = dbm_fetch(emDBM, keydatum);
  120.   TRACE2(invoccache, 2, "The result of fetch = \"%.*s\"", valuedatum.dsize,
  121.     valuedatum.dptr);
  122.   if (valuedatum.dptr != NULL) {
  123.     bcopy(valuedatum.dptr, thevaluespace, valuedatum.dsize);
  124.     *(thevaluespace+valuedatum.dsize) = '\0';
  125.     if (sscanf(thevaluespace, "O0x%x", &resultOID) != 1) assert(FALSE);
  126.     TRACE1(invoccache, 2, "Found it, result OID 0x%08x", resultOID);
  127.     if (! isPossibleAnswer(resultOID, keydatum)) {
  128.       TRACE0(invoccache, 2, "That is not a possible answer.");
  129.     } else {
  130.       result = OTLookup(resultOID);
  131.     }
  132.   }
  133.   if (result == NN) {
  134.     TRACE0(invoccache, 1, "Did not find it");
  135.   } else {
  136.     TRACE2(invoccache, 1, "Result object = 0x%08x %s", result, ATName(result));
  137.   }
  138.   return(result);
  139. }
  140.  
  141. void updateInvocCache(p, answer)
  142. NodePtr p, answer;
  143. {
  144.   NodePtr theOp, theSig, formals, target, opName, args;
  145.   char thekeyspace[200], thevaluespace[32];
  146.   datum keydatum, valuedatum;
  147.   Boolean foundTypeVariable = FALSE;
  148.  
  149.   assert(p->tag == P_INVOC);
  150.   target = p->b.invoc.target;
  151.   target = findManifestValue(target);
  152.   assert(target->tag == P_OBLIT);
  153.   opName = p->b.invoc.opname;
  154.   assert(opName->tag == P_OPNAME);
  155.   TRACE3(invoccache, 1,
  156.     "caching answer for invocation \"%s\" on \"%s\" on line %d",
  157.     ON_Name(opName->b.opname.id),
  158.     ST_SymbolName(target->b.oblit.name->b.symdef.symbol),
  159.     opName->lineNumber);
  160.  
  161.   if (target->b.oblit.id == 0) {
  162.     TRACE0(invoccache, 1, "Cannot execute invocation on oblit without id");
  163.   }
  164.  
  165.   theOp = findObjectOperation(target, opName);
  166.   assert(theOp != NN);
  167.   assert(theOp->tag == P_OPDEF);
  168.  
  169.   theSig = theOp->b.opdef.sig;
  170.   assert(theSig->tag == P_OPSIG);
  171.   formals = theSig->b.opsig.params;
  172.   args = p->b.invoc.args;
  173.  
  174.   /*
  175.    * Now, put the result in the data base.
  176.    */
  177.   foundTypeVariable = buildKey(target, opName, formals, args, thekeyspace);
  178.   if (foundTypeVariable) {
  179.     TRACE0(invoccache, 2, "EI: Non-manifest arguments (or target)");
  180.   }
  181.   
  182.   keydatum.dptr = thekeyspace;
  183.   keydatum.dsize = strlen(thekeyspace);
  184.  
  185.   assert(answer != NULL);
  186.   answer = GETVALUE(answer);
  187.   assert(answer->tag == P_OBLIT || answer->tag == P_ATLIT);
  188.  
  189.   assert(answer->b.oblit.id != 0);
  190.   sprintf(thevaluespace, "O0x%08x", answer->b.oblit.id);
  191.   valuedatum.dptr = thevaluespace;
  192.   valuedatum.dsize = strlen(thevaluespace);
  193.   TRACE2(invoccache, 1, "storing %s with key %s", ATName(answer),
  194.     keydatum.dptr);
  195.   if (dbm_store(emDBM, keydatum, valuedatum, DBM_REPLACE) < 0) assert(FALSE);
  196.   if (!foundTypeVariable) {
  197.     scheduleOutput(answer->b.oblit.id);
  198.     ensureGenerate(answer->b.oblit.id);
  199.   }
  200. }
  201.